/*                                                              *
 * Project name : "Meteor" engine                               *
 * Version      : 1.8                                           *
 * Date         : 2000                                          *
 *                                                              *
 * Copyright    : dReddi                                        *
 */

#include <windows.h>
#include <stdio.h>
#include <cmath>
#include "cgame.h"
#include "externals.h"

// External commands

#define cmdToggleStateVariable          0x100
#define cmdChangeVideoMode              0x101
#define cmdChangeGLDriver               0x102
#define cmdChangeTexFiltering           0x103
#define cmdChangeTexQuality             0x104
#define cmdCommitRenderChanges          0x200
#define cmdCommitSoundChanges           0x201
#define cmdExecConfigFile               0x202
#define cmdStartNewGame                 0x300
#define cmdLoadMap                      0x301
#define cmdPlayAnimation                0x302
#define cmdTakeScreenshot               0x303
#define cmdQuitEngine                   0x304

// Menu codes

#define MENU_MAIN                       1
#define MENU_OPTIONS                    2
#define MENU_EXIT                       3
#define MENU_GLDRIVER                   4
#define MENU_RESOLUTION                 5
#define MENU_RENDERING                  6
#define MENU_SOUND                      7
#define MENU_EFFECTS                    8
#define MENU_TEX_QUALITY                9
#define MENU_TEX_FILTERING              10

// Credits

#define CREDITS_SHOW_TIME               (6000/TIMER_FREQ)
#define CREDITS_DISAPPEAR_TIME          (5000/TIMER_FREQ)

// Credits images

static M_char *CreditsImagesFileName[]=
    {
        "credits1.tx2",
        "credits2.tx2",
        "credits3.tx2",
        "credits4.tx2",
        "credits5.tx2",
        "credits6.tx2",
        "credits7.tx2",
        "credits8.tx2",
        0
};

// OpenGL drivers

static M_char *OpenGLDrivers[] = 
    { 
        "opengl32.dll",
        "opengl.dll",
        "3dfxvgl.dll",
        "3dfxogl.dll" 
    };

// Menu shapes

static M_char *MainMenuShape[]=
	{
		" -------------------- ",
        "|  << MAIN MENU >>   |",
        "|--------------------|",
        "|  Start             |",
        "|  Options           |",
        "|  Exit              |",
        " -------------------- ",
        0
};
        
static M_char *OptionsMenuShape[]=
	{
        " -------------------- ",
        "|   << OPTIONS >>    |",
        "|--------------------|",
        "|  GLDriver          |",
        "|  Resolution        |",
        "|  Rendering         |",
        "|  Sound             |",
        " -------------------- ",
        0
};

static M_char *ExitMenuShape[]=
	{
        " -------------------- ",
        "|    << EXIT >>      |",
        "|--------------------|",
        "|  Yes               |",
        "|  No                |",
        " -------------------- ",
        0
};

static M_char *GLDriverMenuShape[]=
	{
        " -------------------- ",
        "|    << Driver >>    |",
        "|--------------------|",
        "|  Default OpenGL    |",
        "|  SGI OpenGL        |",
        "|  3dfx OpenGL       |",
        " -------------------- ",
        0
};

static M_char *ResolutionMenuShape[]=
	{
        " -------------------- ",
        "|  << RESOLUTION >>  |",
        "|--------------------|",
        "|  320x200 window    |",
        "|  400x300 window    |",
        "|  512x384 window    |",
        "|  640x480 window    |",
        "|  800x600 window    |",
        "|  320x200 full      |",
        "|  400x300 full      |",
        "|  512x384 full      |",
        "|  640x480 full      |",
        "|  800x600 full      |",
        " -------------------- ",
        0
};

static M_char *SoundMenuShape[]=
	{
        " -------------------- ",
        "|    << SOUND >>     |",
        "|--------------------|",
        "|  SFX volume        |",
        "|  Music volume      |",
        "|--------------------|",
        0
};

static M_char *RenderingMenuShape[]=
	{
        " -------------------- ",
        "|   << RENDERING >>  |",
        "|--------------------|",
        "|  Effects           |",
        "|  Texture quality   |",
        "|  Texture filtering |",
        " -------------------- ",
        0
};

static M_char *EffectsMenuShape[]=
	{
        " -------------------- ",
        "|   << EFFECTS >>    |",
        "|--------------------|",
        "|  Shading           |",
        "|  Blending          |",
        "|  Mirrors           |",
        "|  Fog               |",
        "|  Coronas           |",
        "|  Water effect      |",
        "|  Water caustic     |",
        "|  Particles         |",
        "|  Sky panorama      |",
        "|  Sky layers        |",
        " -------------------- ",
        0
};

static M_char *TexQualityMenuShape[]=
	{
        " -------------------- ",
        "|   << QUALITY >>    |",
        "|--------------------|",
        "|  Low               |",
        "|  Medium            |",
        "|  High              |",
        " -------------------- ",
        0
};

static M_char *TexFilteringMenuShape[]=
	{
        " -------------------- ",
        "|  << FILTERING >>   |",
        "|--------------------|",
        "|  Nearest           |",
        "|  Nearest+mipmaps   |",
        "|  Bilinear+mipmaps  |",
        "|  Trilinear+mipmaps |",
        " -------------------- ",
        0
};

static M_char **MenuShape[10] = 
    {
      MainMenuShape,OptionsMenuShape,
      ExitMenuShape,GLDriverMenuShape,
      ResolutionMenuShape,RenderingMenuShape,SoundMenuShape,
      EffectsMenuShape,TexQualityMenuShape,TexFilteringMenuShape
};

/*
 * Convert string to int
 */
int str2int(char *src)
    {
    return atoi(src);
}

/*
 * Convert string to double
 */
double str2double(char *src)
    {
    return atof(src);
}

/*
 * CMyGame class
 */
M_int CMyGame::Init(M_void)
    {
    // Init start-up system variables    
    
    V_PauseRenderer=FALSE;
    V_PausePhysics=FALSE;
    
    V_UseTextures=TRUE;
    V_UseShading=TRUE;
    V_UseBlending=TRUE;
    V_UseMirrors=TRUE;
    V_UseFog=TRUE;
    V_UseCoronas=TRUE;
    V_UseUnderWaterEffect=TRUE;
    V_UseWaterCaustic=TRUE;
    V_UseModels=TRUE;
    V_UseSounds=TRUE;
    V_UseParticles=TRUE;
    V_UsePanoramaSky=TRUE;
    V_UseSkyLayers=TRUE;
    V_GravityG=9.81F;
    V_TexturesQuality=1;
    V_TexturesFiltering=0;
    
    // Video mode
    
    strcpy(OpenGLDll,OpenGLDrivers[0]);
    V_VideoMode=1;
    V_FullScreen=FALSE;
    
    // Sound
    
    V_SoundQuality=22050;
    V_SoundBits=16;
    V_SoundChannels=2;
    
    // Console
    
    V_ConsoleMaxDropY=0.5F;
    V_ConsoleDropSpeed=0.03F;
    V_ConsoleFontsWidth=6;
    V_ConsoleFontsHeight=6;
    V_ConsoleFontsXSpace=1;
    V_ConsoleFontsYSpace=1;
    V_ConsoleBorderWidth=10;
    V_ConsolePromptChar=':';

    // Mouse
    
    V_CaptureMouse=TRUE;
    MousePitchSpeed=-0.022F;
    MouseYawSpeed=0.022F;
        
    // Menu variables
    
    MenuWidth=22;
    MenuFontsWidth=6;
    MenuFontsHeight=6;
    MenuActive=FALSE;
    
    // Disable intro animation and showing FPS
    
    ShowCredits=FALSE;
    ShowFPS=TRUE;
    
    // Default console keys
    
    KeyConsoleActivate=GetKeyCode("~");
        
    // Default menu keys    
    
    KeyMenuActivate=GetKeyCode("escape");
    KeyMenuDown=GetKeyCode("down");
    KeyMenuUp=GetKeyCode("up");
    KeyMenuEnter=GetKeyCode("enter");
    
    // Default player keys    
    
    KeyMoveForward=GetKeyCode("up");
    KeyMoveBackward=GetKeyCode("down");
    KeyStrafeLeft=GetKeyCode(",");
    KeyStrafeRight=GetKeyCode(".");
    KeyTurnLeft=GetKeyCode("left");
    KeyTurnRight=GetKeyCode("right");
    KeyLookUp=GetKeyCode("insert");
    KeyLookDown=GetKeyCode("delete");
    KeyJump=GetKeyCode("space");

    // OK

    return TRUE;
}

M_int CMyGame::Init2(M_void)
    {    
    M_uint i;
    
    // Add resource paths
    
    AddResourcePath("textures\\","*.res");
    AddResourcePath("samples\\","*.res");
    AddResourcePath("music\\","*.res");
    AddResourcePath("maps\\","*.res");
    
    // Load console data    
    
    V_ConsoleFonts=0;
    V_ConsoleImage=0;
    V_ConsoleFontsImage=0;
    
    if (LoadImage("console.tx2",V_ConsoleImage)==FALSE)
        {
        return FALSE;
    }
    if (LoadTransparentImage("fonts.tx2",V_ConsoleFontsImage,0,0,0)==FALSE)
        {
        return FALSE;
    }
    if (MakeFonts(V_ConsoleFontsImage,V_ConsoleFonts,32,130,32,6,6,1,1)==FALSE)
        {
        return FALSE;
    }

    // Load game data    
    
    for(i=1;i<=MAX_CREDITS_IMAGES;i++)
        {
        CreditsImages[i-1]=0;
        if (LoadTransparentImage(CreditsImagesFileName[i-1],CreditsImages[i-1],0,0,0)==FALSE)
            {
            return FALSE;
        }
    }
    
    // Drop console
    
    DropConsole(TRUE);
    
    // Execute config.cfg
    
    ExecConfigFile("config.cfg");

    // OK    
    
    return TRUE;
}

M_int CMyGame::Done(M_void)
    {
    M_uint i;

    // Dispose game data
    
    for(i=1;i<=MAX_CREDITS_IMAGES;i++)
        {
        DeleteImage(CreditsImages[i-1]);
    }
        
    // Dispose console data
    
    DeleteFonts(V_ConsoleFonts);
    DeleteImage(V_ConsoleImage);
    DeleteImage(V_ConsoleFontsImage);

    // OK
    
    return TRUE;
}

M_int CMyGame::FileExists(M_char *filename)
    {
    HANDLE FileHandle;

    FileHandle=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if (FileHandle!=INVALID_HANDLE_VALUE)
        {
        CloseHandle(FileHandle);
        return TRUE;
    }
    else
        {
        return FALSE;
    }
}

M_char* CMyGame::Find3dfxOpenGLDriver(M_void)
    {
    M_char SystemDir[MAX_PATH],temp[MAX_PATH];
    M_uint i;

    // Find driver in current directory
    
    for(i=1;i<=2;i++)
        {
        if (FileExists(OpenGLDrivers[2+(i-1)])==TRUE)
            {
            return OpenGLDrivers[2+(i-1)];
        }
    }
    
    // Find driver in system directory
    
    GetSystemDirectory(SystemDir,MAX_PATH);    
    for(i=1;i<=2;i++)
        {
        sprintf(temp,"%s\\%s",SystemDir,OpenGLDrivers[2+(i-1)]);
        if (FileExists(temp)==TRUE)
            {
            return OpenGLDrivers[2+(i-1)];
        }
    }

    // Driver not found.Return default driver file name

    return OpenGLDrivers[0];
}

M_void CMyGame::MenuBehaviour(M_short key)
    {
    M_ExtCommand extcmd;
    
    switch (MenuLevel)
        {        
        
        // << Main >>        
        
        case MENU_MAIN:
            
            if (key==KeyMenuActivate)
                {
                MenuActive=FALSE;
            }

            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<3))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                switch (MenuSel)
                    {
                    case 1:

                        // --> Start new game

                        extcmd.command=cmdStartNewGame;
                        InsertExternalCommand(&extcmd);
                        break;
                    case 2:

                        // --> Menu "Options"

                        MenuLevel=MENU_OPTIONS;
                        MenuSel=1;
                        break;
                    case 3:

                        // --> Menu "Exit"

                        MenuLevel=MENU_EXIT;
                        MenuSel=1;
                        break;
                }
            }
            break;
        
        // << Exit >>        
        
        case MENU_EXIT:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_MAIN;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<2))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                switch (MenuSel)
                    {
                    case 1:
                        
                        // --> Exit engine
                        
                        extcmd.command=cmdQuitEngine;
                        InsertExternalCommand(&extcmd);
                        break;
                    case 2:
                        
                        // --> Menu "Main"
                        
                        MenuLevel=MENU_MAIN;
                        MenuSel=1;
                        break;
                }
            }               
            break;
        
        // << Options >>        
        
        case MENU_OPTIONS:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_MAIN;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<4))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                switch (MenuSel)
                    {
                    case 1:
                        
                        // --> Menu "GLDriver"
                        
                        MenuLevel=MENU_GLDRIVER;
                        MenuSel=1;
                        break;
                    case 2:
                        
                        // --> Menu "Resolution"
                        
                        MenuLevel=MENU_RESOLUTION;
                        MenuSel=1;
                        break;
                    case 3:
                        
                        // --> Menu "Rendering"
                        
                        MenuLevel=MENU_RENDERING;
                        MenuSel=1;
                        break;
                    case 4:
                        
                        // --> Menu "Sound"
                        
                        //MenuLevel=MENU_SOUND;
                        //MenuSel=1;
                        break;
                }
            }
            break;
        
        // << GLDriver >>        
        
        case MENU_GLDRIVER:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_OPTIONS;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<3))
                {
                MenuSel++;
            }
            
            if (key==KeyMenuEnter) 
                {
                switch (MenuSel)
                    {
                    case 1:
                        {
                        strcpy(extcmd.infostring,OpenGLDrivers[0]);
                        break;
                    }
                    case 2:
                        {
                        strcpy(extcmd.infostring,OpenGLDrivers[1]);
                        break;
                    }
                    case 3:
                        {
                        strcpy(extcmd.infostring,Find3dfxOpenGLDriver());
                        break;
                    }
                }

                extcmd.command=cmdChangeGLDriver;
                InsertExternalCommand(&extcmd);
            }
            break;
        
        // << Resolution >>        
        
        case MENU_RESOLUTION:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_OPTIONS;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<10))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                if (MenuSel<=5)
                    {
                    extcmd.infoint[0]=MenuSel;
                    extcmd.infoint[1]=FALSE;
                    extcmd.infoint[2]=FALSE;
                }
                else
                    {
                    extcmd.infoint[0]=MenuSel-5;
                    extcmd.infoint[1]=TRUE;
                    extcmd.infoint[2]=FALSE;
                }
                
                extcmd.command=cmdChangeVideoMode;
                InsertExternalCommand(&extcmd);
            }
            break;
        
        // << Rendering >>        
        
        case MENU_RENDERING:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_OPTIONS;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<3))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                switch (MenuSel)
                    {
                    case 1:
                        
                        // --> Menu "Effects"
                        
                        MenuLevel=MENU_EFFECTS;
                        MenuSel=1;
                        break;
                    case 2:
                        
                        // --> Menu "Texture quality"
                        
                        MenuLevel=MENU_TEX_QUALITY;
                        MenuSel=1;
                        break;
                    case 3:
                        
                        // --> Menu "Texture filtering"
                        
                        MenuLevel=MENU_TEX_FILTERING;
                        MenuSel=1;
                        break;
                }
            }
            break;
        
        // << Effects >>        
        
        case MENU_EFFECTS:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_RENDERING;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<10))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                extcmd.infoint[0]=MenuSel;
                extcmd.command=cmdToggleStateVariable;
                InsertExternalCommand(&extcmd);
            }
            break;
        
        // << Texture quality >>        
        
        case MENU_TEX_QUALITY:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_RENDERING;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<3))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {
                extcmd.infoint[0]=4-MenuSel;
                extcmd.command=cmdChangeTexQuality;
                InsertExternalCommand(&extcmd);
                
                // Go to render menu.Changes will take effect when new map loads
                
                MenuLevel=MENU_RENDERING;
                MenuSel=1;
            }
            break;
        
        // << Filtering >>        
        
        case MENU_TEX_FILTERING:
            
            if (key==KeyMenuActivate)
                {
                MenuLevel=MENU_RENDERING;
                MenuSel=1;
            }
            
            if ((key==KeyMenuUp) && (MenuSel>1))
                {
                MenuSel--;
            }
            
            if ((key==KeyMenuDown) && (MenuSel<4))
                {
                MenuSel++;
            }

            if (key==KeyMenuEnter) 
                {                        
                extcmd.infoint[0]=MenuSel-1;
                extcmd.command=cmdChangeTexFiltering;
                InsertExternalCommand(&extcmd);
            }
            break;
    }
}

M_void CMyGame::Timer(M_void)
    {
    M_short key,shift;

    // Read key
    
    LastKeyPressed(key,shift);

    // Console
    
    if (V_ConsoleActive==TRUE)
        {
        if (key==KeyConsoleActivate)
            {
            RaiseConsole(FALSE);
        }
    }
    else
        {
        if (key==KeyConsoleActivate)
            {
            DropConsole(FALSE);
        }
    }

    // Menu
    
    if (MenuActive==TRUE)
        {        
        // Console up
        
        RaiseConsole(TRUE);

        // Menu behaviour         
        
        MenuBehaviour(key);
    }
    else
        {    
        
        // Activate menu?
        
        if (key==KeyMenuActivate)
            {            
            // Yes
            
            MenuLevel=1;
            MenuSel=1;
            MenuActive=TRUE;
        }
    }

    // Key binding
    
    if ((V_ConsoleActive==FALSE) && (MenuActive==FALSE))
        {
        if (BindKeys[key].binded==TRUE)
            {
            ExecuteConsoleCommand(BindKeys[key].command);
        }
    }
    
    // Pause physics if console or menu active    
    
    if ((V_ConsoleActive==TRUE) || (MenuActive==TRUE))
        {
        V_PausePhysics=TRUE;
    }
    else
        {
        V_PausePhysics=FALSE;
    }

    // Do credits
    
    if (ShowCredits==TRUE)
        {
        CurCreditsTime++;
        if (CurCreditsTime>=CREDITS_SHOW_TIME)
            {
            CurCreditsTime=0;
            if (CurCreditsImage<MAX_CREDITS_IMAGES)
                {
                CurCreditsImage++;
            }
            else
                {
                CurCreditsImage=1;
            }
        }
        else
            {
            if (CurCreditsTime>CREDITS_DISAPPEAR_TIME)
                {
                CurCreditsAlpha=0;
            }
            else
                {
                CurCreditsAlpha=1;
            }
        }
    }
}

M_void CMyGame::Render2d(M_void)
    {
    M_int x1,y1,x2,y2;
    M_uint xofs,yofs,i;
    M_char buffer[16];
    
    // Render credits
    
    if (ShowCredits==TRUE)
        {
        x1=(M_int)V_WindowWidth*0.25F;
        y1=(M_int)V_WindowHeight*0.7F;
        x2=(M_int)V_WindowWidth*0.75F;
        y2=(M_int)V_WindowHeight*0.8F;   
        RenderImage(CreditsImages[CurCreditsImage-1],x1,y1,x2,y2,CurCreditsAlpha);
    }

    // Prepare fonts texture
    
    PrepareFonts(V_ConsoleFonts);
    
    // Render FPS
    
    if (ShowFPS==TRUE)
        {
        sprintf(buffer,"%d FPS",V_FPS);
        DrawText(V_ConsoleFonts,buffer,0,V_WindowHeight-MenuFontsHeight,MenuFontsWidth,MenuFontsHeight,1);
    }
    
    // Render menu    
    
    if (MenuActive==TRUE)
        {
        // Prepare drawing               
        
        xofs=(V_WindowWidth/2)-((MenuWidth/2)*MenuFontsWidth);
        yofs=3*MenuFontsHeight;

        // Draw menu shape        
        
        i=0;
        while (MenuShape[MenuLevel-1][i]!=0)
            {            
            // Draw line            
            
            DrawText(V_ConsoleFonts,MenuShape[MenuLevel-1][i],xofs,yofs,MenuFontsWidth,MenuFontsHeight,1);
            
            // Draw selection arrow            
            
            if ( ((i+1)-3)==MenuSel )
                {
                DrawText(V_ConsoleFonts,">",xofs+MenuFontsWidth,yofs,MenuFontsWidth,MenuFontsHeight,1);
            }

            // Next line
            
            yofs+=MenuFontsHeight;
            i++;
        }
    }
    else
        {        
        // Draw info text       
        
        DrawText(V_ConsoleFonts,"Press ESC to toggle menu",0,0,MenuFontsWidth,MenuFontsHeight,1);
    }
}

M_void CMyGame::ParseExternalCommand(M_ExtCommand *extcmd)
    {
    M_MapStart MapStart;
    M_ActorData ActorData;
    M_char filename[32];
    M_uint i;
    FILE *f;

    // Parse commands

    if (extcmd->command==cmdToggleStateVariable)
        {
        // Toggle state variable
        
        switch (extcmd->infoint[0])
            {
            case 1:
                V_UseShading=TRUE-V_UseShading;
                break;
            case 2:
                V_UseBlending=TRUE-V_UseBlending;
                break;
            case 3:
                V_UseMirrors=TRUE-V_UseMirrors;
                break;
            case 4:
                V_UseFog=TRUE-V_UseFog;
                break;
            case 5:
                V_UseCoronas=TRUE-V_UseCoronas;
                break;
            case 6:
                V_UseUnderWaterEffect=TRUE-V_UseUnderWaterEffect;
                break;
            case 7:
                V_UseWaterCaustic=TRUE-V_UseWaterCaustic;
                break;
            case 8:
                V_UseParticles=TRUE-V_UseParticles;
                break;
            case 9:
                V_UsePanoramaSky=TRUE-V_UsePanoramaSky;
                break;
            case 10:
                V_UseSkyLayers=TRUE-V_UseSkyLayers;
                break;
        }
    }
    if (extcmd->command==cmdChangeVideoMode)
        {
        // Set video mode
        
        V_VideoMode=extcmd->infoint[0];

        // Set fullscreen or windowed mode
        
        V_FullScreen=extcmd->infoint[1];
        
        // Set OpenGL dll file name if needed
        
        if (extcmd->infoint[2]==TRUE)
            {
            strcpy(OpenGLDll,extcmd->infostring);
         }
        
        // Commit render changes
        CommitRenderChanges();
    }
    if (extcmd->command==cmdChangeGLDriver)
        {
        // Set OpenGL dll file name
        
        strcpy(OpenGLDll,extcmd->infostring);
        
        // Commit render changes
        
        CommitRenderChanges();
    }
    if (extcmd->command==cmdChangeTexFiltering)
        {
        // Set texture filtering
        
        V_TexturesFiltering=extcmd->infoint[0];

        // Commit render changes
        
        CommitRenderChanges();
    }
    if (extcmd->command==cmdChangeTexQuality)
        {
        // Set texture quality
        
        V_TexturesQuality=extcmd->infoint[0];
    }
    if (extcmd->command==cmdCommitRenderChanges)
        {
        // Commit render changes
        
        CommitRenderChanges();
    }
    if (extcmd->command==cmdCommitSoundChanges)
        {
        // Commit sound changes
        
        CommitSoundChanges();
    }
    if (extcmd->command==cmdExecConfigFile)
        {
        // Execute config file
        
        ExecConfigFile(extcmd->infostring);
    }
    if (extcmd->command==cmdStartNewGame)
        {
        // Don't show credits
        
        ShowCredits=FALSE;
        
        // Start new game
        
        if (NewGame()==FALSE)
            {
            return;
        }

        // Load map
        
        if (LoadMap("demo.w3d")==FALSE)
            {
            return;
        }

        // Find map start
        
        if (GetMapStart("MAP START",MapStart)==FALSE)
            {
            return;
        }
        
        // Add player actor        
        
        ActorData.position=MapStart.position;
        ActorData.orientation=MapStart.orientation;
        ActorData.sector=MapStart.sector;        
        
        if (AddActor("player.male",ActorData,actPlayerActor,PlayerActorHandle)==FALSE)
            {
            return;
        }
        
        // Disable console and menu
        
        RaiseConsole(FALSE);
        MenuActive=FALSE;
    }        
    if (extcmd->command==cmdLoadMap)
        {
        // Don't show credits
        
        ShowCredits=FALSE;
        
        // Start new game
        
        if (NewGame()==FALSE)
            {
            return;
        }

        // Load map
        
        if (LoadMap(extcmd->infostring)==FALSE)
            {
            return;
        }

        // Find map start
        
        if (GetMapStart("MAP START",MapStart)==FALSE)
            {
            return;
        }
        
        // Add player actor
        
        ActorData.position=MapStart.position;
        ActorData.orientation=MapStart.orientation;
        ActorData.sector=MapStart.sector;
        
        if (AddActor("player.male",ActorData,actPlayerActor,PlayerActorHandle)==FALSE)
            {
            return;
        }
        
        // Disable console and menu
        
        RaiseConsole(FALSE);
        MenuActive=FALSE;
    }
    if (extcmd->command==cmdPlayAnimation)
        {
        // Don't show credits
        
        ShowCredits=FALSE;
        
        // Start new game
        
        if (NewGame()==FALSE)
            {
            return;
        }
        
        // Load map
        
        if (LoadMap(extcmd->infostring)==FALSE)
            {
            return;
        }
        
        // Play animation
        
        if (PlayAnimation()==FALSE)
            {
            return;
        }
        
        // Detect intro animation
        
        if (strcmp(extcmd->infostring,"intro.w3d")==0)
            {
            CurCreditsImage=1;
            CurCreditsAlpha=1.0F;
            CurCreditsTime=0;
            ShowCredits=TRUE;
        }
        
        // Disable console and menu
        
        RaiseConsole(FALSE);
        MenuActive=FALSE;
    }
    if (extcmd->command==cmdTakeScreenshot)
        {
        // Search for empty slot
        
        for(i=0;i<=1000;i++)
            {
            sprintf(filename,"shot%d.tga",i);
            f=fopen(filename,"r");
            if (f==NULL)
                {
                // Save window bitmap to file
                
                SaveWindowBmp(filename);

                // Console info
                
                InsertConsoleLine("Screen saved!");

                // OK
                
                break;
            }
            else
                {
                fclose(f);
            }
        }
    }
    if (extcmd->command==cmdQuitEngine)
        {
        // Quit engine
        
        QuitEngine();
    }

    // Trigger commands ( placed on map )
    
    if (extcmd->command==1000)
        {
        // Play music 
        
        PlayMusicByName(extcmd->infostring);
    }
    if (extcmd->command==1001)
        {
        // Stop current music
        
        StopMusic();
    }
}

M_void CMyGame::ParseConsoleCommand(M_int noparams,M_char **params)
    {
    M_uint i;
    M_short key;
    M_ExtCommand extcmd;
    
    // Parse console commands : game commands    
    
    if ((strcmp(params[0],"map")==0) && (noparams==2))
        {
        // Load map
        
        strcpy(extcmd.infostring,params[1]);
        extcmd.command=cmdLoadMap;
        InsertExternalCommand(&extcmd);
        return;
    }
    
    if ((strcmp(params[0],"anim")==0) && (noparams==2))
        {
        // Play animation
        
        strcpy(extcmd.infostring,params[1]);
        extcmd.command=cmdPlayAnimation;
        InsertExternalCommand(&extcmd);
        return;
    }

    // Parse console commands : render & window commands
    
    if ((strcmp(params[0],"r_filter")==0) && (noparams==2))
        {
        // Read filtering
        
        i=str2int(params[1]);
        if ((i>=0) && (i<=4))
            {
            // Set filtering
            
            V_TexturesFiltering=i;
        }
    }
    if ((strcmp(params[0],"r_gamma")==0) && (noparams==2))
        {
        // Set gamma correction
        
        SetGamma((M_float)str2double(params[1]));
        return;
    }
    if ((strcmp(params[0],"v_gldriver")==0) && (noparams==2))
        {
        // Set OpenGL driver
        
        strcpy(OpenGLDll,params[1]);
        return;
    }    
    if ((strcmp(params[0],"v_vidmode")==0) && (noparams==3))
        {
        // Read video mode
        
        i=str2int(params[1]);
        if ((i>=vid320x200) && (i<=vid2048x1280))
            {            
            // Set video mode
            
            V_VideoMode=i;
            
            // Set windowed or fullscreen
            
            if (strcmp(params[2],"full")==0)
                {
                V_FullScreen=TRUE;
            }
            else
                {
                V_FullScreen=FALSE;
            }
        }
        return;
    }
    if ((strcmp(params[0],"v_restart")==0) && (noparams==1))
        {
        // Restart video system
        
        extcmd.command=cmdCommitRenderChanges;
        InsertExternalCommand(&extcmd);
        return;
    }
    
    // Parse console commands : sound commands
    
    if ((strcmp(params[0],"s_vol")==0) && (noparams==3))
        {
        // Read SFX volume
        
        i=str2int(params[1]);
        if ((i>=0) && (i<=64))
            {
            // Set SFX volume
            
            V_SFXVolume=i;
        }
        
        // Read music volume
        
        i=str2int(params[2]);
        if ((i>=0) && (i<=64))
            {
            // Set music volume
            
            V_MusicVolume=i;
        }
        return;
    }
    if ((strcmp(params[0],"s_quality")==0) && (noparams==2))
        {
        // Read sound quality
        
        i=str2int(params[1]);
        if ((i>=8000) && (i<=44100))
            {
            // Set sound quality
            
            V_SoundQuality=i;
        }
        return;
    }
    if ((strcmp(params[0],"s_channels")==0) && (noparams==2))
        {
        // Read sound channels
        
        i=str2int(params[1]);
        if ((i>=1) && (i<=2))
            {
            // Set sound channels
            
            V_SoundChannels=i;
        }
        return;
    }
    if ((strcmp(params[0],"s_bits")==0) && (noparams==2))
        {
        // Read sound bits
        
        i=str2int(params[1]);
        if ((i>=1) && (i<=2))
            {
            // Set sound bits
            
            V_SoundBits=i;
        }
        return;
    }
    if ((strcmp(params[0],"s_restart")==0) && (noparams==1))
        {
        // Restart sound system
        
        extcmd.command=cmdCommitSoundChanges;
        InsertExternalCommand(&extcmd);
        return;
    }    

    // Parse console commands : system commands    
    
    if ((strcmp(params[0],"bind")==0) && (noparams==3))
        {
        // Get key code        
        
        key=(GetKeyCode(params[1]) & 0xff);
        
        // Bind player keys
        
        if (strcmp(params[2],"moveforward")==0)
            {
            KeyMoveForward=key;
            return;
        }
        if (strcmp(params[2],"movebackward")==0)
            {
            KeyMoveBackward=key;
            return;
        }
        if (strcmp(params[2],"strafeleft")==0)
            {
            KeyStrafeLeft=key;
            return;
        }
        if (strcmp(params[2],"straferight")==0)
            {
            KeyStrafeRight=key;
            return;
        }
        if (strcmp(params[2],"turnleft")==0)
            {
            KeyTurnLeft=key;
            return;
        }
        if (strcmp(params[2],"turnright")==0)
            {
            KeyTurnRight=key;
            return;
        }
        if (strcmp(params[2],"lookup")==0)
            {
            KeyLookUp=key;
            return;
        }
        if (strcmp(params[2],"lookdown")==0)
            {
            KeyLookDown=key;
            return;
        }
        if (strcmp(params[2],"jump")==0)
            {
            KeyJump=key;
            return;
        }

        // Bind system keys
        
        if (strcmp(params[2],"toggleconsole")==0)
            {
            KeyConsoleActivate=key;
            return;
        }
        if (strcmp(params[2],"togglemenu")==0)
            {
            KeyMenuActivate=key;
            return;
        }
        
        // Bind key
        
        BindKeys[key].binded=TRUE;
        strcpy(BindKeys[key].command,params[2]);
        return;
    }
    if ((strcmp(params[0],"mousepitch")==0) && (noparams==2))
        {
        MousePitchSpeed=(M_float)str2double(params[1]);
        return;
    }
    if ((strcmp(params[0],"mouseyaw")==0) && (noparams==2))
        {
        MouseYawSpeed=(M_float)str2double(params[1]);
        return;
    }
    if ((strcmp(params[0],"exec")==0) && (noparams==2))
        {
        // Exec config file
        
        extcmd.command=cmdExecConfigFile;
        strcpy(extcmd.infostring,params[1]);
        InsertExternalCommand(&extcmd);
        return;
    }
    if ((strcmp(params[0],"scrshot")==0) && (noparams==1))
        {
        // Take screenshot
        
        extcmd.command=cmdTakeScreenshot;
        InsertExternalCommand(&extcmd);
        return;
    }
    if ((strcmp(params[0],"fps")==0) && (noparams==2))
        {
        // Enable/disable fps
        
        i=str2int(params[1]);
        if (i==1)
            {
            ShowFPS=TRUE;
        }
        else
            {
            ShowFPS=FALSE;
        }
        return;
    }
    if ((strcmp(params[0],"quit")==0) && (noparams==1))
        {
        // Quit engine
        
        extcmd.command=cmdQuitEngine;
        InsertExternalCommand(&extcmd);
        return;
    }
}
